home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-11-20 | 40.5 KB | 1,418 lines |
- ;------------------------------------------------------------------------------
- ;
- ; File : AudioPort.a
- ;
- ; Author : Stéphane TAVENARD
- ;
- ; $VER: AudioPort.a 1.3 (22/07/1995)
- ;
- ; (C) Copyright 1995-1995 Stéphane TAVENARD
- ; All Rights Reserved
- ;
- ; #Rev| Date | Comment
- ; ----|----------|--------------------------------------------------------
- ; 0 |05/06/1995| Initial revision ST
- ; 1 |06/06/1995| First release (no more C code) ST
- ; 2 |19/06/1995| Added FreeSignal in DeletePort ST
- ; 3 |23/06/1995| Aminet release ST
- ; 4 |09/07/1995| Use now ex_EClockFrequency for period calculation ST
- ; 5 |22/07/1995| Added volume control for 16-bit samples ST
- ; 5 |24/07/1995| Added Mixing frequency ST
- ;
- ; ------------------------------------------------------------------------
- ;
- ; An Audio Port 8 or 16 bits, mono or stereo
- ;
- ;------------------------------------------------------------------------------
-
-
- IFND INCLUDE_SOURCE
- incdir "include:"
- include "exec/funcdef.i"
- include "exec/exec.i"
- include "exec/exec_lib.i"
- include "devices/audio.i"
- include "hardware/custom.i"
- ENDC
-
- include "AudioPort.i"
-
- IFND INCLUDE_SOURCE
- XREF _custom
-
- CALLEXEC MACRO
- move.l (_SysBase).w,a6
- jsr _LVO\1(a6)
- ENDM
- _SysBase EQU 4
-
- ENDC
-
-
- XDEF @AU_close
- XDEF @AU_open
- XDEF @AU_write
-
- ; Audio registers
-
- AU_PTR equ ac_ptr
- AU_LEN equ ac_len
- AU_PER equ ac_per
- AU_VOL equ ac_vol
- AU_DAT equ ac_dat
-
- AUDIO_PRI equ ADALLOC_MAXPREC
-
- section ASMDATA,data
-
- even
- AU_AllChannels dc.b 15
- even
- AU_LRChannels dc.b 3, 5, 10, 12
- even
- AU_DEVICE_NAME AUDIONAME
- even
- AU_PORT_NAME dc.b 'AudioPort', 0
-
- section ASMCODE,code
-
- ;
- ; Calculate audio period with help of frequency
- ;
- ; d0.l = frequency
- ; -> d0.l = period
- ; a0, d1 is affected
- ;
- calculate_period
- tst.l d0
- beq calculate_period9
- move.l (_SysBase).w,a0
- move.l ex_EClockFrequency(a0),d1
- mulu.l #5,d1 ; d1 = Audio DMA base freq.
- divu.l d0,d1
- ; move.l #100000000,d1
- ; mulu.w #28,d0
- ; divu.l d0,d1
- move.l d1,d0
- calculate_period9 rts
-
-
- ;
- ; Delete a port
- ;
- ; a0: MsgPort *
- ;
- DeletePort movem.l a2,-(sp)
- move.l a0,a2
- tst.l MP+LN_NAME(a2)
- beq DeletePort1
- move.l a2,a1
- CALLEXEC RemPort
- DeletePort1 clr.l d0
- move.b MP_SIGBIT(a2),d0
- CALLEXEC FreeSignal
- move.b #-1,MP+LN_TYPE(a2)
- move.l #-1,MP_MSGLIST+LH_HEAD(a2)
- move.l a2,a1
- move.l #MP_SIZE,d0
- CALLEXEC FreeMem
- movem.l (sp)+,a2
- rts
- ;
- ; Create a port
- ;
- ; a0: name
- ; d0.b: pri
- ; -> d0 = MsgPort * (=0 if fail)
- ;
- CreatePort movem.l a2-a3/d2-d3,-(sp)
- move.l d0,d2
- move.l a0,a2
- moveq.b #-1,d0
- CALLEXEC AllocSignal
- cmp.b #-1,d0
- beq CreatePort8 ; Signal error
- move.l d0,d3
- move.l #MP_SIZE,d0
- move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
- CALLEXEC AllocMem
- tst.l d0
- beq CreatePort7 ; Memory error
- move.l d0,a3
- move.l a2,MP+LN_NAME(a3)
- move.b d2,MP+LN_PRI(a3)
- move.b #NT_MSGPORT,MP+LN_TYPE(a3)
- move.b #PA_SIGNAL,MP_FLAGS(a3)
- move.b d3,MP_SIGBIT(a3)
- clr.l d0
- move.l d0,a1
- CALLEXEC FindTask
- move.l d0,MP_SIGTASK(a3)
- tst.l a2
- beq CreatePort1
- move.l a3,a1
- CALLEXEC AddPort
- move.l a3,d0
- bra CreatePort9
- CreatePort1 lea MP_MSGLIST(a3),a1
- NEWLIST a1
- move.l a3,d0
- bra CreatePort9
- CreatePort7 move.l d3,d0
- CALLEXEC FreeSignal
- CreatePort8 clr.l d0
- CreatePort9 movem.l (sp)+,a2-a3/d2-d3
- rts
-
- ;
- ; Delete an Ext IORequest
- ;
- ; a0: IORequest *
- ;
- DeleteExtIO
- tst.l a0
- beq DeleteExtIO9
- move.b #-1,IO+MN+LN_TYPE(a0)
- move.l #-1,IO_DEVICE(a0)
- move.l #-1,IO_UNIT(a0)
- move.l a0,a1
- clr.l d0
- move.w IO+MN_LENGTH(a0),d0
- CALLEXEC FreeMem
- DeleteExtIO9 rts
-
- ;
- ; Create an Ext IORequest
- ;
- ; a0: MsgPort *
- ; d0.w: Size
- ; -> d0 = IORequest * (=0 if fail)
- ;
- CreateExtIO movem.l a2/d2,-(sp)
- tst.l a0
- beq CreateExtIO9
- and.l #$0000FFFF,d0
- move.l d0,d2
- move.l a0,a2
- move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
- CALLEXEC AllocMem
- move.l d0,a0
- tst.l a0
- beq CreateExtIO9
- move.b #NT_MESSAGE,IO+MN+LN_TYPE(a0)
- move.w d2,IO+MN_LENGTH(a0)
- move.l a2,IO+MN_REPLYPORT(a0)
- CreateExtIO9 move.l a0,d0
- movem.l (sp)+,a2/d2
- rts
-
- ;
- ; Free a DeviceBlock
- ;
- ; a0: DeviceBlock ptr
- ;
- FreeDeviceBlock movem.l a2,-(sp)
- move.l a0,a2
- tst.l a0
- beq FreeDeviceBlock9
- move.l IO+MN_REPLYPORT(a2),d0
- beq FreeDeviceBlock8
- move.l d0,a0
- bsr DeletePort
- FreeDeviceBlock8 move.l a2,a0
- bsr DeleteExtIO
- FreeDeviceBlock9 movem.l (sp)+,a2
- rts
-
- ;
- ; Get a DeviceBlock
- ;
- ; d0.w: Size
- ; -> d0 = DeviceBlock ptr (=0 if fail)
- ;
- GetDeviceBlock movem.l d2-d3,-(sp)
- move.l d0,d2
- clr.l d0
- move.l d0,a0
- bsr CreatePort
- move.l d0,d3
- beq GetDeviceBlock9
- move.l d3,a0
- move.l d2,d0
- bsr CreateExtIO
- tst.l d0
- bne GetDeviceBlock9
- move.l d3,a0
- bsr DeletePort
- clr.l d0
- GetDeviceBlock9 movem.l (sp)+,d2-d3
- rts
-
-
- ;
- ; Close Audio channels
- ;
- ; a0: hard_port
- ;
- close_audio_channels
- XDEF close_audio_channels
- movem.l a2-a3,-(sp)
- move.l a0,a2
- move.l hp_port(a2),a3
- move.l hp_intnum(a2),d0
- move.l hp_old_interrupt(a2),a1
- CALLEXEC SetIntVector
- move.l IOAudio+IO+MN_REPLYPORT(a3),d0
- beq close_audio_channel1
- move.l d0,a0
- bsr DeletePort
- close_audio_channel1 tst.l IOAudio+IO_DEVICE(a3)
- beq close_audio_channel2
- move.l a3,a1
- CALLEXEC CloseDevice
- close_audio_channel2 move.l a3,a0
- bsr DeleteExtIO
- movem.l (sp)+,a2-a3
- rts
-
- ;
- ; Open Audio channels
- ;
- ; a0: hard_port
- ; -> d0.l = 0 if fail, 1 if ok
- ;
- open_audio_channels
- XDEF open_audio_channels
- movem.l a2-a3,-(sp)
- move.l a0,a2
- clr.l d0
- move.l d0,a1
- CALLEXEC FindTask
- move.l d0,hp_task(a2)
- move.l #ioa_SIZEOF,d0
- bsr GetDeviceBlock
- move.l d0,hp_port(a2)
- beq open_audio_channels9
- move.l d0,a3
- clr.l d0
- move.l IOAudio+IO+MN_REPLYPORT(a3),a0
- move.b MP_SIGBIT(a0),d0
- move.l d0,hp_signal(a2)
- btst.b #AUFB_16BITS,hp_flags(a2)
- beq open_audio_channels1
- lea AU_AllChannels,a1
- moveq.l #1,d1
- bra open_audio_channels2
- open_audio_channels1 lea AU_LRChannels,a1
- moveq.l #4,d1
- open_audio_channels2 move.l a1,ioa_Data(a3)
- move.l d1,ioa_Length(a3)
- move.b #AUDIO_PRI,IOAudio+IO+MN+LN_PRI(a3)
- move.l a3,a1
- lea AU_DEVICE_NAME,a0
- moveq.l #0,d0
- moveq.l #0,d1
- CALLEXEC OpenDevice
- tst.b d0
- bne open_audio_channels8 ; Open error
- move.l IOAudio+IO_UNIT(a3),hp_channels_bitmap(a2)
- move.l a2,a1
- bsr @ASM_audio_init
- lea hp_audio_interrupt(a2),a1
- move.b #NT_INTERRUPT,IS+LN_TYPE(a1)
- move.b #0,IS+LN_PRI(a1)
- lea AU_PORT_NAME,a0
- move.l a0,IS+LN_NAME(a1)
- move.l a2,IS_DATA(a1)
- lea @ASM_audio_handler,a0
- move.l a0,IS_CODE(a1)
- move.l hp_intnum(a2),d0
- CALLEXEC SetIntVector
- move.l d0,hp_old_interrupt(a2)
- moveq.l #1,d0
- bra open_audio_channels9
- open_audio_channels8 move.l a3,a0
- bsr FreeDeviceBlock
- clr.l hp_port(a2)
- clr.l d0
- open_audio_channels9 movem.l (sp)+,a2-a3
- rts
-
- ;
- ; Delete Audio port
- ;
- ; a0: audio_port
- ;
- delete_audio_port
- XDEF delete_audio_port
- movem.l d2-d3/a2-a4,-(sp)
- tst.l a0
- beq delete_audio_port9
- move.l a0,a2
- move.l au_hard_port(a2),a3
- tst.l a3
- beq delete_audio_port8
- ; free USER input buffers
- move.l a3,a0
- bsr free_input_buffers
- ; free mixing buffer
- move.l a3,a0
- bsr free_mixing_buffer
- ; free audio buffers
- clr.l d4
- delete_audio_port3 move.w d4,d0
- move.l a3,a0
- bsr free_audio_buffer
- addq.w #1,d4
- cmp.w #2,d4
- blt.s delete_audio_port3
- ; free hard port
- move.l a3,a1
- move.l #hp_sizeof,d0
- CALLEXEC FreeMem
- delete_audio_port8 ; free audio port
- move.l a2,a1
- move.l #au_sizeof,d0
- CALLEXEC FreeMem
- delete_audio_port9 movem.l (sp)+,d2-d3/a2-a4
- rts
-
- ; Free the USER input buffers
- ;
- ; a0.l = hard_port *
- ;
- free_input_buffers
- XDEF free_input_buffers
- movem.l d2/a2/a6,-(sp)
- move.l a0,a2
- move.l hp_wave_max_length(a2),d2
- beq.s free_input_buffers9
- btst.b #AUFB_16BITS,hp_flags(a2)
- beq.s free_input_buffers0
- add.l d2,d2 ; 16-bit buffers
- free_input_buffers0 move.l hp_input_l_wave(a2),a1
- tst.l a1
- beq.s free_input_buffers1
- move.l d2,d0
- CALLEXEC FreeMem
- clr.l hp_input_l_wave(a2)
- free_input_buffers1 move.l hp_input_r_wave(a2),a1
- tst.l a1
- beq.s free_input_buffers9
- move.l d2,d0
- CALLEXEC FreeMem
- clr.l hp_input_r_wave(a2)
- free_input_buffers9 clr.l hp_wave_max_length(a2)
- movem.l (sp)+,d2/a2/a6
- rts
-
- ; Allocate the input buffers
- ;
- ; d0.l = input sample max length
- ; a0.l = hard_port *
- ; -> d0.l = 0 if failure
- ;
- allocate_input_buffers
- XDEF allocate_input_buffers
- movem.l d2-d3/a2/a6,-(sp)
- move.l a0,a2 ; a2 = hard_port *
- move.l d0,d2
- move.l d0,hp_wave_max_length(a2)
- btst.b #AUFB_16BITS,hp_flags(a2)
- beq.s allocate_input_buff1 ; 8-bit sample
- add.l d2,d2
- allocate_input_buff1 move.l #MEMF_PUBLIC|MEMF_CLEAR,d3
- move.l d2,d0
- move.l d3,d1
- CALLEXEC AllocMem
- tst.l d0
- beq allocate_input_buff6 ; memory error
- move.l d0,hp_input_l_wave(a2)
- btst.b #AUFB_STEREO,hp_flags(a2)
- beq allocate_input_buff2
- move.l d2,d0
- move.l d3,d1
- CALLEXEC AllocMem
- tst.l d0
- beq allocate_input_buff6 ; memory error
- move.l d0,hp_input_r_wave(a2)
- allocate_input_buff2 moveq.l #-1,d0
- bra.s allocate_input_buff9
- allocate_input_buff6 move.l a2,a0
- bsr free_input_buffers
- clr.l d0
- allocate_input_buff9 movem.l (sp)+,d2-d3/a2/a6
- rts
-
-
-
- ; Free the mixing buffer
- ;
- ; a0.l = hard_port *
- ;
- free_mixing_buffer
- XDEF free_mixing_buffer
- movem.l a2/a6,-(sp)
- move.l a0,a2
- move.l hp_mixing_buffer(a2),a1
- tst.l a1
- beq.s free_mixing_buffer9
- move.l hp_mixing_max_size(a2),d0
- CALLEXEC FreeMem
- clr.l hp_mixing_buffer(a2)
- free_mixing_buffer9 clr.l hp_mixing_max_size(a2)
- movem.l (sp)+,a2/a6
- rts
-
- ; (Re)Allocate the mixing buffer if necessary
- ;
- ; d0.l = mixing sample length
- ; a0.l = hard_port *
- ; -> d0.l = 0 if failure
- ;
- allocate_mixing_buffer
- XDEF allocate_mixing_buffer
- movem.l d2/d5/a3/a6,-(sp)
- move.l a0,a3 ; a3 = hard_port *
- move.b hp_flags(a3),d5
- btst #AUFB_16BITS,d5
- beq.s allocate_mixing_buf1 ; 8-bit sample
- add.l d0,d0
- allocate_mixing_buf1 cmp.l hp_mixing_max_size(a3),d0
- ble allocate_mixing_buf8 ; Actual mixing buffer is ok
- move.l d0,d2 ; d2 = New mixing size
- move.l a3,a0
- bsr free_mixing_buffer
- move.l d2,d0
- move.l #MEMF_PUBLIC,d1
- CALLEXEC AllocMem
- tst.l d0
- beq.s allocate_mixing_buf6 ; memory error
- move.l d0,hp_mixing_buffer(a3)
- move.l d2,hp_mixing_max_size(a3)
- bra.s allocate_mixing_buf8
- allocate_mixing_buf6 clr.l d0
- bra.s allocate_mixing_buf9
- allocate_mixing_buf8 moveq.l #-1,d0
- allocate_mixing_buf9 movem.l (sp)+,d2/d5/a3/a6
- rts
-
-
-
- ; Free one audio buffer
- ;
- ; d0.w = buffer number
- ; a0.l = hard_port *
- ;
- free_audio_buffer
- XDEF free_audio_buffer
- movem.l d2-d3/a2/a6,-(sp)
- move.l (hp_wave_max_size,a0,d0.w*4),d2 ; Actual size
- ; tst.l d2
- ; beq free_audio_buffer9
- clr.l (hp_wave_max_size,a0,d0.w*4) ; New size is 0
- lea (hp_l_wave_h,a0,d0.w*4),a2 ; first buffer ptr
- moveq.w #4-1,d3 ; 4 buffer to free
- free_audio_buffer1 move.l (a2),a1
- tst.l a1
- beq.s free_audio_buffer2 ; This buffer is free
- move.l d2,d0
- CALLEXEC FreeMem
- clr.l (a2)
- free_audio_buffer2 addq.l #2*4,a2
- dbra d3,free_audio_buffer1
- free_audio_buffer9
- movem.l (sp)+,d2-d3/a2/a6
- rts
-
- ; (Re)Allocate one audio buffer if necessary
- ;
- ; d0.l = sample size
- ; d1.w = buffer number
- ; a0.l = hard_port *
- ; -> d0.l = 0 if failure
- ;
- allocate_audio_buffer
- XDEF allocate_audio_buffer
- movem.l d2-d5/a2-a3/a6,-(sp)
- move.l d0,d2 ; d2 = sample size
- move.l d1,d3 ; d3 = # buffer
- move.l #MEMF_CHIP,d4 ; d4 = memory type
- move.l a0,a3 ; a3 = hard_port *
- move.l (hp_wave_max_size,a3,d3.w*4),d0 ; Actual size
- cmp.l d0,d2
- ble allocate_audio_buff8 ; Actual size is ok
- move.l d3,d0
- move.l a3,a0
- bsr free_audio_buffer ; Free this audio buffer
- move.l d2,(hp_wave_max_size,a3,d3.w*4) ; New size
- move.b hp_flags(a3),d5
- move.l d2,d0
- move.l d4,d1
- CALLEXEC AllocMem
- tst.l d0
- beq allocate_audio_buff6 ; memory error
- move.l d0,(hp_l_wave_h,a3,d3.w*4)
- btst #AUFB_16BITS,d5
- beq allocate_audio_buff2 ; 8-bit only !
- move.l d2,d0
- move.l d4,d1
- CALLEXEC AllocMem
- tst.l d0
- beq allocate_audio_buff6 ; memory error
- move.l d0,(hp_l_wave_l,a3,d3.w*4)
- allocate_audio_buff2 btst #AUFB_STEREO,d5 ; mono samples !
- beq allocate_audio_buff3
- move.l d2,d0
- move.l d4,d1
- CALLEXEC AllocMem
- tst.l d0
- beq allocate_audio_buff6 ; memory error
- move.l d0,(hp_r_wave_h,a3,d3.w*4)
- btst #AUFB_16BITS,d5 ; 8-bit only !
- beq allocate_audio_buff3
- move.l d2,d0
- move.l d4,d1
- CALLEXEC AllocMem
- tst.l d0
- beq allocate_audio_buff6 ; memory error
- move.l d0,(hp_r_wave_l,a3,d3.w*4)
- allocate_audio_buff3 bra.s allocate_audio_buff8
- allocate_audio_buff6 ; memory error -> free allocated buffers
- move.l d3,d0
- move.l a3,a0
- bsr free_audio_buffer ; Free this audio buffer
- clr.l d0
- bra.s allocate_audio_buff9
- allocate_audio_buff8 moveq.l #-1,d0
- allocate_audio_buff9 movem.l (sp)+,d2-d5/a2-a3/a6
- rts
-
- ;
- ; New Audio port
- ;
- ; d0.b : flags
- ; d1.l : buffer_size
- ; -> d0.l = audio_port (=NULL if fail)
- ;
- new_audio_port
- XDEF new_audio_port
- movem.l d2-d5/a2-a4,-(sp)
- move.l d0,d2
- move.l d1,d3
- tst.l d1
- ble new_audio_port8 ; <= 0
- cmp.l #$20000,d1
- bge new_audio_port8 ; >= $20000
- btst #0,d1
- bne new_audio_port8 ; odd buffer_size !
- move.l #au_sizeof,d0
- move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
- CALLEXEC AllocMem
- tst.l d0
- beq new_audio_port8 ; memory error
- move.l d0,a2
- move.l #hp_sizeof,d0
- move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
- CALLEXEC AllocMem
- tst.l d0
- beq new_audio_port6 ; memory error
- move.l d0,a3
- move.l a3,au_hard_port(a2)
- ; move.l d3,hp_wave_max_length(a3) (#5 set by allocate_input_buffers)
- move.b d2,hp_flags(a3)
- ; default values
- moveq.l #23,d0
- move.l d0,hp_current_period(a3)
- moveq.w #64,d0
- move.w d0,hp_l_vol(a3)
- move.w d0,hp_r_vol(a3)
- ;
- ; allocate USER input buffers #5
- ;
- move.l a3,a0
- move.l d3,d0
- bsr allocate_input_buffers
- tst.l d0
- beq new_audio_port6 ; memory error
- move.l hp_input_l_wave(a3),au_l_wave(a2)
- move.l hp_input_r_wave(a3),au_r_wave(a2)
- ;
- ; allocate audio buffers #5
- ;
- clr.l d4
- new_audio_port1 move.l d3,d0 ; sample size
- move.w d4,d1 ; buffer number
- move.l a3,a0 ; hard_port *
- bsr allocate_audio_buffer
- tst.l d0
- beq new_audio_port6 ; memory error
- addq.w #1,d4
- cmp.w #2,d4 ; double buffering
- blt.s new_audio_port1
- clr.l hp_active_wave(a3)
-
- move.l a2,d0
- bra new_audio_port9
- new_audio_port6 move.l a2,a0
- bsr delete_audio_port
- new_audio_port8 clr.l d0
- new_audio_port9 movem.l (sp)+,d2-d5/a2-a4
- rts
-
-
- ;
- ; Process an input wave
- ;
- ; a0: audio_port
- ; -> d0.l = 0 if failure
- ;
- process_wave
- movem.l d2-d5/a2-a4,-(sp)
- move.l a0,a3 ; a3 = audio_port
- move.l au_hard_port(a3),a4 ; a4 = hard_port
- move.l hp_active_wave(a4),d3
- move.l au_wave_length(a3),d5 ; = sample length
- beq process_wave85 ; No sample -> no process
- move.l hp_current_period(a4),d0
- move.l d0,(hp_wave_period,a4,d3.w*4)
- btst.b #AUFB_MIXING,au_flags(a3)
- beq process_wave0 ; no mixing
- move.l d5,d2 ; d2.l = wave_length
- move.l hp_input_frequency(a4),d0
- move.l hp_output_frequency(a4),d1
- bsr audio_mix_size
- move.l d0,hp_mixing_length(a4)
- move.l d0,d5 ; = new sample length
- beq process_wave8 ; failure
- move.l a4,a0 ; and d0.l = mixing length
- bsr allocate_mixing_buffer
- tst.l d0
- beq process_wave8 ; failure
- process_wave0 move.l d5,(hp_wave_length,a4,d3.w*4) ; = sample length
- ; Allocate audio buffers if necessary
- move.l d5,d0 ; out sample length
- move.l d3,d1 ; buffer number
- move.l a4,a0 ; hard_port *
- bsr allocate_audio_buffer
- tst.l d0
- beq process_wave8 ; allocate failure
- btst.b #AUFB_16BITS,hp_flags(a4)
- bne process_wave5 ; 16-bit process
- ;
- ; 8-bit samples processing
- ;
- ; 1) Mix Mono or Left sample ?
- move.l au_l_wave(a3),a0 ; input sample
- tst.l a0
- beq process_wave2
- btst.b #AUFB_MIXING,au_flags(a3)
- beq process_wave1 ; no mixing
- move.l hp_mixing_buffer(a4),a1 ; BYTE *output_sample
- move.l hp_input_frequency(a4),d0
- move.l hp_output_frequency(a4),d1
- move.l d5,d2
- bsr @ASM_audio_8_mix
- move.l hp_mixing_buffer(a4),a0
- process_wave1 ; 2) Copy processed wave to audio buffers
- move.l (hp_l_wave_h,a4,d3.w*4),a1 ; audio buffer
- tst.l a1
- beq process_wave2
- move.l d5,d0 ; #bytes to copy
- CALLEXEC CopyMem
- process_wave2 ; 3) Mix Right or Stereo sample ?
- btst.b #AUFB_STEREO,hp_flags(a4)
- beq process_wave3 ; Mono sample
- move.l au_r_wave(a3),a0 ; input sample
- tst.l a0
- beq process_wave4
- btst.b #AUFB_MIXING,au_flags(a3)
- beq process_wave3 ; no mixing
- move.l hp_mixing_buffer(a4),a1 ; BYTE *output_sample
- move.l hp_input_frequency(a4),d0
- move.l hp_output_frequency(a4),d1
- move.l d5,d2
- bsr @ASM_audio_8_mix
- move.l hp_mixing_buffer(a4),a0
- process_wave3 ; 4) Copy processed wave to audio buffers
- move.l (hp_r_wave_h,a4,d3.w*4),a1 ; audio buffer
- tst.l a1
- beq process_wave4
- move.l d5,d0 ; #bytes to copy
- CALLEXEC CopyMem
- process_wave4 moveq.l #-1,d0
- bra process_wave9
- ;
- process_wave5 ; 16-bit samples processing
- ;
- ; 1) Mix Mono or Left sample ?
- move.l au_l_wave(a3),a0 ; input sample
- tst.l a0
- beq process_wave65
- btst.b #AUFB_MIXING,au_flags(a3)
- beq process_wave61 ; no mixing
- move.l hp_mixing_buffer(a4),a1 ; BYTE *output_sample
- move.l hp_input_frequency(a4),d0
- move.l hp_output_frequency(a4),d1
- move.l d5,d2
- bsr @ASM_audio_16_mix
- move.l hp_mixing_buffer(a4),a0
- process_wave61 ; 2) Split 16-bit sample to 8-bit audio buffers
- move.l d5,d0
- move.l (hp_l_wave_h,a4,d3.w*4),a1
- move.l (hp_l_wave_l,a4,d3.w*4),a2
- move.w hp_l_vol(a4),d1
- bsr @ASM_audio_split_vol
- process_wave65 ; 3) Mix Right or Stereo sample ?
- btst.b #AUFB_STEREO,hp_flags(a4)
- beq process_wave75 ; Mono sample
- move.l au_r_wave(a3),a0 ; input sample
- tst.l a0
- beq process_wave75
- btst.b #AUFB_MIXING,au_flags(a3)
- beq process_wave71 ; no mixing
- move.l hp_mixing_buffer(a4),a1 ; BYTE *output_sample
- move.l hp_input_frequency(a4),d0
- move.l hp_output_frequency(a4),d1
- move.l d5,d2
- bsr @ASM_audio_16_mix
- move.l hp_mixing_buffer(a4),a0
- process_wave71 ; 4) Split 16-bit sample to 8-bit audio buffers
- move.l d5,d0
- move.l (hp_r_wave_h,a4,d3.w*4),a1
- move.l (hp_r_wave_l,a4,d3.w*4),a2
- move.w hp_r_vol(a4),d1
- bsr @ASM_audio_split_vol
- process_wave75 moveq.l #-1,d0
- bra process_wave9
- process_wave8 clr.l d0
- bra process_wave9
- process_wave85 clr.l (hp_wave_length,a4,d3.w*4) ; sample length = 0
- moveq.l #-1,d0
- process_wave9 movem.l (sp)+,d2-d5/a2-a4
- rts
-
- ;
- ; Write to Audio port
- ;
- ; a0: audio_port
- ;
- @AU_write
- AU_write movem.l d2-d5/a2-a4,-(sp)
- tst.l a0
- beq AU_write9
- move.l a0,a3
- move.l au_hard_port(a3),a4 ; a4 = hard_port
- clr.l d2
- move.b au_flags(a3),d2
- btst #AUFB_FREQ,d2
- beq AU_write1
- move.l au_frequency(a3),d0
- move.l d0,hp_input_frequency(a4) ; #5
- btst #AUFB_MIXING,d2 ; #5
- beq AU_write0 ; #5
- move.l au_mixing_frequency(a3),d0 ; #5
- AU_write0 move.l d0,hp_output_frequency(a4) ; #5
- bsr calculate_period
- move.l d0,hp_current_period(a4)
- AU_write1 btst #AUFB_VOL,d2
- beq AU_write2
- move.w au_l_vol(a3),hp_l_vol(a4)
- move.w au_r_vol(a3),hp_r_vol(a4)
- AU_write2 btst #AUFB_FILTER,d2
- beq AU_write3
- bclr #AUFB_FILTER,hp_flags(a4) ; ???
- tst.b au_filter_on(a3)
- beq AU_write3
- bset #AUFB_FILTER,hp_flags(a4) ; ???
- AU_write3 move.b au_command(a3),d3
- cmp.b #AUC_CONTROL,d3
- bne AU_write4
- ; btst #AUFB_FREQ,d2
- ; move.l a4,a1
- ; bsr @ASM_audio_per
- AU_write31 btst #AUFB_VOL,d2
- beq AU_write32
- move.l a4,a1
- bsr @ASM_audio_vol
- AU_write32 btst #AUFB_FILTER,d2
- beq AU_write33
- move.l a4,a1
- bsr @ASM_audio_filter
- AU_write33 bra AU_write9
- AU_write4 cmp.b #AUC_WRITE,d3
- bne AU_write5
- move.l a3,a0 ; a0 = audio_port *
- bsr process_wave ; #5
- tst.l d0
- beq AU_write9 ; process_wave error
- move.l a4,a1
- bsr @ASM_audio_write
- move.l hp_active_wave(a4),d3
- bchg #0,d3
- move.l d3,hp_active_wave(a4) ; active_wave ^= 1
- btst.b #AUFB_NOWAIT,au_flags(a3)
- bne AU_write42
- clr.l d0
- move.l hp_signal(a4),d1
- bset d1,d0
- CALLEXEC Wait
- AU_write42
- ; #5: if no input buffers, use audio buffers for USER
- ; btst #AUFB_16BITS,d2
- ; tst.l hp_input_l_wave(a4)
- ; bne AU_write43 ; Ok, left input buffer exist
- ; move.l (hp_l_wave_h,a4,d3.w*4),au_l_wave(a3)
- ;AU_write43 tst.l hp_input_r_wave(a4)
- ; bne AU_write44 ; Ok, Right input buffer exist
- ; move.l (hp_r_wave_h,a4,d3.w*4),au_r_wave(a3)
- AU_write44 bra AU_write9
- AU_write5 cmp.b #AUC_STOP,d3
- bne AU_write6
- move.l a4,a1
- bsr @ASM_audio_stop
- bra AU_write9
- AU_write6 cmp.b #AUC_CONTINUE,d3
- bne AU_write9
-
- AU_write9 movem.l (sp)+,d2-d5/a2-a4
- rts
-
- ;
- ; Close an Audio port
- ;
- ; a0 = audio_port
- ;
- @AU_close
- AU_close movem.l a2-a3,-(sp)
- tst.l a0
- beq AU_close9
- move.l a0,a2
- move.l au_hard_port(a2),a3
- move.l a3,a1
- bsr @ASM_audio_stop
- move.l a3,a0
- bsr close_audio_channels
- move.l a2,a0
- bsr delete_audio_port
- AU_close9 movem.l (sp)+,a2-a3
- rts
-
- ;
- ; Open an Audio port
- ;
- ; d0.b : flags
- ; d1.l : buffer_size
- ; -> d0.l = audio_port or NULL if fail
- ;
- @AU_open
- AU_open movem.l a2-a3,-(sp)
- bsr new_audio_port
- tst.l d0
- beq AU_open9
- move.l d0,a2
- move.l au_hard_port(a2),a3
- move.l a3,a0
- bsr open_audio_channels
- tst.l d0
- bne AU_open1
- move.l a2,a0
- bsr delete_audio_port
- clr.l d0
- bra AU_open9
- AU_open1 move.l hp_signal(a3),d0
- move.b d0,au_signal(a2)
- move.l a2,d0
- AU_open9 movem.l (sp)+,a2-a3
- rts
-
-
- ; Audio Split 16bits -> 2x8bits for 14bit audio
- ;
- ; a0 = WORD *Wave16bits
- ; a1 = BYTE *WaveH8bits
- ; a2 = BYTE *WaveL8bits
- ; d0 = ULONG Wave16Length
- ;
- @ASM_audio_split
- movem.l d0-d7/a0-a2,-(sp)
- move.w #128,d7
- move.w #$FF00,d6
- move.w #$FF,d5
- lsr.l #1,d0
- subq.l #1,d0
- ASM_audio_split1
- move.w (a0)+,d1
- move.w d1,d2
- add.w d7,d1
- bvs.s ASM_audio_split2
- and.w d6,d1
- asr.b #2,d2
- lsl.w #8,d2
- ASM_audio_split3
- move.w (a0)+,d3
- move.w d3,d4
- add.w d7,d3
- bvs.s ASM_audio_split4
- lsr.w #8,d3
- asr.b #2,d4
- and.w d5,d4
- ASM_audio_split5
- or.w d3,d1
- move.w d1,(a1)+
- or.w d4,d2
- move.w d2,(a2)+
- dbra d0,ASM_audio_split1
- movem.l (sp)+,d0-d7/a0-a2
- rts
- ASM_audio_split2
- move.w #$7F00,d1
- move.w d1,d2
- bra.s ASM_audio_split3
- ASM_audio_split4
- moveq.w #$7F,d3
- move.w d1,d4
- bra.s ASM_audio_split5
-
-
-
- ; #5 Audio Split 16bits + Volume set -> 2x8bits for 14bit audio
- ;
- ; a0 = WORD *Wave16bits
- ; a1 = BYTE *WaveH8bits
- ; a2 = BYTE *WaveL8bits
- ; d0 = ULONG Wave16Length
- ; d1.w = Volume (64 = Normal)
- ;
- @ASM_audio_split_vol
- cmp.w #64,d1 ; If volume is normal, use
- beq @ASM_audio_split ; ASM_audio_split instead
- movem.l d0-d7/a0-a3,-(sp)
- move.w d1,d7
- lea.l 128,a3
- move.w #$FF00,d6
- move.w #$FF,d5
- lsr.l #1,d0
- subq.l #1,d0
- ASM_audio_split_vol1
- move.w (a0)+,d1
- muls.w d7,d1
- asr.l #6,d1
- move.w d1,d2
- add.w a3,d1
- bvs.s ASM_audio_split_vol2
- and.w d6,d1
- asr.b #2,d2
- lsl.w #8,d2
- ASM_audio_split_vol3
- move.w (a0)+,d3
- muls.w d7,d3
- asr.l #6,d3
- move.w d3,d4
- add.w a3,d3
- bvs.s ASM_audio_split_vol4
- lsr.w #8,d3
- asr.b #2,d4
- and.w d5,d4
- ASM_audio_split_vol5
- or.w d3,d1
- move.w d1,(a1)+
- or.w d4,d2
- move.w d2,(a2)+
- dbra d0,ASM_audio_split_vol1
- movem.l (sp)+,d0-d7/a0-a3
- rts
- ASM_audio_split_vol2
- move.w #$7F00,d1
- move.w d1,d2
- bra.s ASM_audio_split_vol3
- ASM_audio_split_vol4
- moveq.w #$7F,d3
- move.w d1,d4
- bra.s ASM_audio_split_vol5
-
-
- AUDIO_16_MIX_SHIFT equ 14
-
- ; #5 Audio mix 8-bit sample at freq f1 -> 8-bit sample freq f2
- ;
- ; a0 = BYTE *input_sample
- ; a1 = BYTE *output_sample
- ; d0.l = input freq
- ; d1.l = output freq
- ; d2.l = output sample size
- ;
-
- @ASM_audio_8_mix
- XDEF @ASM_audio_8_mix
- movem.l d2-d7,-(sp)
-
- move.l d2,d7 ; d7 = output sample size
- tst.w d1
- beq ASM_audio_8_mix9
- move.l #1<<AUDIO_16_MIX_SHIFT,d6 ; d6 = t_max
- mulu.w d6,d0
- divu.l d1,d0
- move.l d0,d5 ; d5 = t_inc
- move.l d6,d4
- add.l d4,d4 ; d4 = t_out = 2*t_max
- moveq.l #AUDIO_16_MIX_SHIFT,d1
- ASM_audio_8_mix1
- cmp.l d6,d4
- blt.s ASM_audio_8_mix2
- ASM_audio_8_mix10 move.l d3,d2 ; d2 = e0, d3 = e1
- move.b (a0)+,d3
- ext.w d3
- sub.l d6,d4 ; t_out -= t_max
- cmp.l d6,d4
- bge.s ASM_audio_8_mix10
- ASM_audio_8_mix2 move.w d3,d0
- sub.w d2,d0 ; e1-e0
- muls.w d4,d0 ; (e1-e0) * t_out
- asr.l d1,d0
- add.w d2,d0 ; e0 + ((e1-e0) * t_out)>>14
- move.b d0,(a1)+
- add.l d5,d4 ; t_out += t_inc
- subq.l #1,d7
- bne.s ASM_audio_8_mix1
- ASM_audio_8_mix9 movem.l (sp)+,d2-d7
- rts
-
-
-
-
- ; #6 Audio mix 16-bit sample at freq f1 -> 16-bit sample freq f2
- ;
- ; a0 = WORD *input_sample
- ; a1 = WORD *output_sample
- ; d0.l = input freq
- ; d1.l = output freq
- ; d2.l = output sample size
- ;
- @ASM_audio_16_mix
- XDEF @ASM_audio_16_mix
- movem.l d2-d7,-(sp)
-
- move.l d2,d7 ; d7 = output sample size
- tst.w d1
- beq ASM_audio_16_mix9
- move.l #1<<AUDIO_16_MIX_SHIFT,d6 ; d6 = t_max
- mulu.w d6,d0
- divu.l d1,d0
- move.l d0,d5 ; d5 = t_inc
- move.l d6,d4
- add.l d4,d4 ; d4 = t_out = 2*t_max
- moveq.l #AUDIO_16_MIX_SHIFT,d1
- ASM_audio_16_mix1
- cmp.l d6,d4
- blt.s ASM_audio_16_mix2
- ASM_audio_16_mix10 move.l d3,d2 ; d2 = e0, d3 = e1
- move.w (a0)+,d3
- ext.l d3
- sub.l d6,d4 ; t_out -= t_max
- cmp.l d6,d4
- bge.s ASM_audio_16_mix10
- ASM_audio_16_mix2 move.l d3,d0
- sub.l d2,d0 ; e1-e0
- muls.l d4,d0 ; (e1-e0) * t_out
- asr.l d1,d0
- add.l d2,d0 ; e0 + ((e1-e0) * t_out)>>13
- move.w d0,(a1)+
- add.l d5,d4 ; t_out += t_inc
- subq.l #1,d7
- bne.s ASM_audio_16_mix1
- ASM_audio_16_mix9 movem.l (sp)+,d2-d7
- rts
-
-
-
- ; #5 Audio mix sample size calculation
- ;
- ; d0.l = input_freq
- ; d1.l = mixing_freq
- ; d2.l = wave_length: input sample size (0x20000 max)
- ; -> d0.l = mixing_length: output mixing sample size
- ;
- ; Formula is :
- ; mixing_length = (wave_length * t_max) / t_inc
- ; t_max = 1<<AUDIO_16_MIX_SHIFT
- ; t_inc = (t_max * input_freq) / mixing_freq
- ;
- audio_mix_size
- XDEF audio_mix_size
- movem.l d2-d3,-(sp)
- tst.l d1
- beq audio_mix_size9
- move.l #1<<AUDIO_16_MIX_SHIFT,d3
- mulu.l d3,d0
- divu.l d1,d0 ; d0 = t_inc
- mulu.l d3,d2
- ; add.l d0,d2 ; Suppressed 24/07/1995
- divu.l d0,d2
- audio_mix_size9 move.l d2,d0 ; d0 = mixing sample size
- and.b #$FE,d0 ; Assume size to be even
- cmp.l #$20000,d0 ; max size for audio dma's
- ble audio_mix_size10
- move.l #$20000,d0
- audio_mix_size10 movem.l (sp)+,d2-d3
- rts
-
- ; Audio init
- ;
- ; a1 = struct hard_port *hport
- ;
- @ASM_audio_init
- movem.l d2-d4,-(sp)
- lea _custom,a0
- move.l hp_channels_bitmap(a1),d1
- btst.b #AUFB_16BITS,hp_flags(a1)
- bne.s ASM_audio_ini5 ; 16 bits
- move.w #aud0,d2
- btst #0,d1
- bne.s ASM_audio_ini1
- move.w #aud3,d2
- ASM_audio_ini1 move.w d2,hp_l_channel_h(a1)
- move.w #aud1,d2
- btst #1,d1
- bne.s ASM_audio_ini2
- move.w #aud2,d2
- ASM_audio_ini2 move.w d2,hp_r_channel_h(a1)
- bra.s ASM_audio_ini6
- ASM_audio_ini5
- move.w #aud0,hp_l_channel_h(a1)
- move.w #aud1,hp_r_channel_h(a1)
- move.w #aud2,hp_r_channel_l(a1)
- move.w #aud3,hp_l_channel_l(a1)
- ASM_audio_ini6
- move.w #$00FF,hp_adkcon(a1) ; adkcon
- move.w d1,d2 ; audena
- and.w #$000F,d2
- move.w d2,hp_audena(a1)
- move.w d1,d2 ; intdis
- lsl.w #7,d2
- and.w #$0780,d2
- move.w d2,hp_intdis(a1)
- clr.l d2 ; intena (enable only 1 channel int)
- moveq.l #7,d3 ; start int level
- moveq.w #3-1,d4
- ASM_audio_ini7
- lsr.l #1,d1
- bcs.s ASM_audio_ini8
- addq.l #1,d3
- dbra d4,ASM_audio_ini7
- ASM_audio_ini8
- move.l d3,hp_intnum(a1)
- bset d3,d2
- bset #15,d2
- move.w d2,hp_intena(a1)
-
- movem.l (sp)+,d2-d4
- bsr.w @ASM_audio_stop
- rts
-
- ; Audio stop wave
- ;
- ; a1 = struct hard_port *hport
- ;
- @ASM_audio_stop
- lea _custom,a0
- clr.b hp_playing(a1) ; Audio stopped
- moveq.l #0,d0
- move.w hp_l_channel_h(a1),d1
- move.w d0,(AU_VOL,a0,d1.w) ; Volume -> 0
- move.w hp_r_channel_h(a1),d1
- move.w d0,(AU_VOL,a0,d1.w) ; Volume -> 0
- btst.b #AUFB_16BITS,hp_flags(a1)
- beq.s ASM_audio_stop2 ; 8 bits
- move.w hp_l_channel_l(a1),d1
- move.w d0,(AU_VOL,a0,d1.w) ; Volume -> 0
- move.w hp_r_channel_l(a1),d1
- move.w d0,(AU_VOL,a0,d1.w) ; Volume -> 0
- ASM_audio_stop2
- move.w hp_audena(a1),$96(a0) ; DMACON AUDxEN -> 0
- move.w hp_adkcon(a1),$9E(a0) ; ADKCON clr all audio bits
- move.w hp_intdis(a1),$9C(a0) ; Clr audio x interrupts
- move.w hp_intdis(a1),$9A(a0) ; INTENA audio 0 -> 0
- rts
-
- ; Audio set filter
- ;
- ; a1 = struct hard_port *hport
- ;
- @ASM_audio_filter
- lea $BFE001,a0
- btst.b #AUFB_FILTER,hp_flags(a1)
- bne.s ASM_audio_filter5
- bset #1,(a0)
- bra.s ASM_audio_filter9
- ASM_audio_filter5 bclr #1,(a0)
- ASM_audio_filter9 rts
-
-
- ; Audio set volume
- ;
- ; a1 = struct hard_port *hport
- ;
- @ASM_audio_vol
- lea _custom,a0
- move.w hp_l_channel_h(a1),d0
- move.w hp_r_channel_h(a1),d1
- btst.b #AUFB_16BITS,hp_flags(a1)
- bne.w ASM_audio_vol5 ; 16 bits
- move.w hp_l_vol(a1),(AU_VOL,a0,d0.w)
- move.w hp_r_vol(a1),(AU_VOL,a0,d1.w)
- ASM_audio_vol5 rts
-
- ; Audio set period
- ;
- ; a1 = struct hard_port *hport
- ; d0.l = period
- ;
- @ASM_audio_per
- movem.l d2-d7,-(sp)
- lea _custom,a0
- ; move.l hp_active_wave(a1),d1
- ; bchg #0,d1
- ; move.l (hp_current_period,a1,d1.w*4),d0
- move.w hp_l_channel_h(a1),d4
- move.w hp_r_channel_h(a1),d5
- CALLEXEC Disable
- btst.b #AUFB_16BITS,hp_flags(a1)
- bne.w ASM_audio_per5 ; 16 bits
- move.w d0,(AU_PER,a0,d4.w)
- move.w d0,(AU_PER,a0,d5.w)
- bra.s ASM_audio_per9
- ASM_audio_per5
- move.w hp_l_channel_l(a1),d6
- move.w hp_r_channel_l(a1),d7
- move.w d0,(AU_PER,a0,d4.w)
- move.w d0,(AU_PER,a0,d6.w)
- move.w d0,(AU_PER,a0,d5.w)
- move.w d0,(AU_PER,a0,d7.w)
- ASM_audio_per9
- CALLEXEC Enable
- movem.l (sp)+,d2-d7
- rts
-
- ; Audio write wave
- ;
- ; a1 = struct hard_port *hport
- ;
- @ASM_audio_write
- movem.l d2-d7,-(sp)
- lea _custom,a0
- move.l hp_active_wave(a1),d1
- asl.l #2,d1 ; d1*4
- move.l hp_wave_period(a1,d1.l),d0
- move.l d0,hp_next_period(a1)
- move.w hp_l_channel_h(a1),d4
- move.w hp_r_channel_h(a1),d5
- CALLEXEC Disable
- btst.b #AUFB_16BITS,hp_flags(a1)
- bne.w ASM_audio_wr5 ; 16 bits
- tst.b hp_playing(a1) ;#5
- bne ASM_audio_wr0
- move.w d0,(AU_PER,a0,d4.w)
- move.w d0,(AU_PER,a0,d5.w)
- ASM_audio_wr0
- move.w hp_l_vol(a1),(AU_VOL,a0,d4.w)
- move.w hp_r_vol(a1),(AU_VOL,a0,d5.w)
- move.l hp_l_wave_h(a1,d1.l),d0
- move.l d0,(AU_PTR,a0,d4.w)
- btst #AUFB_STEREO,hp_flags(a1)
- beq.s ASM_audio_wr1 ; Mono output
- move.l hp_r_wave_h(a1,d1.l),d0
- ASM_audio_wr1 move.l d0,(AU_PTR,a0,d5.w)
-
- clr.b hp_end_of_play(a1) ; Not end of play ?
- move.l hp_wave_length(a1,d1.l),d0
- asr.l #1,d0 ; Count in word
- move.w d0,(AU_LEN,a0,d4.w)
- move.w d0,(AU_LEN,a0,d5.w)
-
- bne.w ASM_audio_wr7 ; Ok wave_length > 0 -> play audio
- st.b hp_end_of_play(a1) ; wave_length = 0 -> end of play
- bra.w ASM_audio_wr7
-
- ASM_audio_wr5
- move.w hp_l_channel_l(a1),d6
- move.w hp_r_channel_l(a1),d7
- tst.b hp_playing(a1) ;#5
- bne ASM_audio_wr50
- move.w d0,(AU_PER,a0,d4.w)
- move.w d0,(AU_PER,a0,d6.w)
- move.w d0,(AU_PER,a0,d5.w)
- move.w d0,(AU_PER,a0,d7.w)
- ASM_audio_wr50
- moveq.w #$40,d0
- move.w d0,(AU_VOL,a0,d4.w)
- move.w d0,(AU_VOL,a0,d5.w)
- moveq.w #$01,d0
- move.w d0,(AU_VOL,a0,d6.w)
- move.w d0,(AU_VOL,a0,d7.w)
- move.l hp_l_wave_h(a1,d1.l),d0
- move.l hp_l_wave_l(a1,d1.l),d2
- move.l d0,(AU_PTR,a0,d4.w)
- move.l d2,(AU_PTR,a0,d6.w)
- btst #AUFB_STEREO,hp_flags(a1)
- beq.s ASM_audio_wr6 ; Mono output
- move.l hp_r_wave_h(a1,d1.l),d0
- move.l hp_r_wave_l(a1,d1.l),d2
- ASM_audio_wr6 move.l d0,(AU_PTR,a0,d5.w)
- move.l d2,(AU_PTR,a0,d7.w)
-
- clr.b hp_end_of_play(a1) ; Not end of play ?
- move.l hp_wave_length(a1,d1.l),d0
- asr.l #1,d0 ; Count in word
- move.w d0,(AU_LEN,a0,d4.w)
- move.w d0,(AU_LEN,a0,d5.w)
- move.w d0,(AU_LEN,a0,d6.w)
- move.w d0,(AU_LEN,a0,d7.w)
-
- bne.s ASM_audio_wr7 ; Ok wave_length > 0 -> play audio
- st.b hp_end_of_play(a1) ; wave_length = 0 -> end of play
- ASM_audio_wr7
- tst.b hp_playing(a1)
- bne.s ASM_audio_wr9 ; Always playing (started)
- st.b hp_playing(a1) ; Started
- move.w hp_audena(a1),d0
- bset #15,d0
- move.w d0,$96(a0) ; DMACON AUDxEN -> 1
- move.w hp_adkcon(a1),$9E(a0) ; ADKCON clr all audio bits
- move.w hp_intdis(a1),$9C(a0) ; Clr audio x interrupts
- move.w hp_intena(a1),$9A(a0) ; INTENA audio 0 -> 1
- ASM_audio_wr9
- st.b hp_dma_loaded(a1) ; Dma is loaded
- CALLEXEC Enable
- movem.l (sp)+,d2-d7
- rts
-
- ; Audio interrupt handler
- ;
- ; a1 = DATA = struct hard_port *hport
- ;
- @ASM_audio_handler
- lea _custom,a0
- move.w hp_intdis(a1),$9C(a0) ; Clr audio x interrupts
- move.l hp_next_period(a1),d0
- bsr @ASM_audio_per ; #5
- tst.b hp_dma_loaded(a1)
- bne.s ASM_audio_handler1 ; Ok DMA was loaded -> signal
- bsr @ASM_audio_stop ; DMA is empty !!! -> stop audio, no signal
- bra.s ASM_audio_handler9
- ASM_audio_handler1
- clr.b hp_dma_loaded(a1) ; DMA become free
- tst.b hp_end_of_play(a1) ; end of play ?
- beq.s ASM_audio_handler2
- bsr @ASM_audio_stop
- ASM_audio_handler2
- move.l hp_signal(a1),d1
- clr.l d0
- bset d1,d0
- move.l hp_task(a1),a1
- CALLEXEC Signal
- ASM_audio_handler9
- clr.l d0
- rts
-
-